/**
 * @file
 * Tests for ExpansionGraph class.
 */

#include "expansion_graph_test.h"

void ExpansionGraphTest::SetUp()
{
  g1 = new ExpansionGraph<StringVertexEdge, StringVertexEdge>();

  g1_v1 = new StringVertexEdge(1,"a");
  g1_v2 = new StringVertexEdge(2,"a");
  g1_v3 = new StringVertexEdge(3,"a");
  g1_v4 = new StringVertexEdge(4,"b");
  g1_v5 = new StringVertexEdge(5,"b");
  g1_v6 = new StringVertexEdge(6,"b");
  g1_v7 = new StringVertexEdge(7,"c");
  g1_v8 = new StringVertexEdge(8,"c");
  g1_v9 = new StringVertexEdge(9,"c");

  g1_e1 = new StringVertexEdge(1,"x");
  g1_e2 = new StringVertexEdge(2,"x");
  g1_e3 = new StringVertexEdge(3,"x");
  g1_e4 = new StringVertexEdge(4,"y");
  g1_e5 = new StringVertexEdge(5,"y");
  g1_e6 = new StringVertexEdge(6,"y");
  g1_e7 = new StringVertexEdge(7,"z");
  g1_e8 = new StringVertexEdge(8,"z");
  g1_e9 = new StringVertexEdge(9,"u");
  g1_e10 = new StringVertexEdge(10,"u");
  g1_e11 = new StringVertexEdge(11,"u");

  g1->add_vertex(g1_v1);
  g1->add_vertex(g1_v2);
  g1->add_vertex(g1_v3);
  g1->add_vertex(g1_v4);
  g1->add_vertex(g1_v5);
  g1->add_vertex(g1_v6);
  g1->add_vertex(g1_v7);
  g1->add_vertex(g1_v8);
  g1->add_vertex(g1_v9);

  g1->add_edge(g1_e1,g1_v1,g1_v2);
  g1->add_edge(g1_e2,g1_v2,g1_v3);
  g1->add_edge(g1_e3,g1_v3,g1_v4);
  g1->add_edge(g1_e4,g1_v4,g1_v5);
  g1->add_edge(g1_e5,g1_v5,g1_v6);
  g1->add_edge(g1_e6,g1_v6,g1_v7);
  g1->add_edge(g1_e7,g1_v7,g1_v8);
  g1->add_edge(g1_e8,g1_v8,g1_v9);
  g1->add_edge(g1_e9,g1_v9,g1_v1);
  g1->add_edge(g1_e10,g1_v1,g1_v7);
  g1->add_edge(g1_e11,g1_v1,g1_v8);

  
  g2 = new ExpansionGraph<StringVertexEdge, StringVertexEdge>();

  g2_v1 = new StringVertexEdge(1,"a");
  g2_v2 = new StringVertexEdge(2,"a");
  g2_v3 = new StringVertexEdge(3,"a");
  g2_v4 = new StringVertexEdge(4,"b");
  g2_v5 = new StringVertexEdge(5,"b");
  g2_v6 = new StringVertexEdge(6,"b");
  g2_v7 = new StringVertexEdge(7,"c");
  g2_v8 = new StringVertexEdge(8,"c");
  g2_v9 = new StringVertexEdge(9,"c");

  g2_e1 = new StringVertexEdge(1,"x");
  g2_e2 = new StringVertexEdge(2,"x");
  g2_e3 = new StringVertexEdge(3,"x");
  g2_e4 = new StringVertexEdge(4,"y");
  g2_e5 = new StringVertexEdge(5,"y");
  g2_e6 = new StringVertexEdge(6,"y");
  g2_e7 = new StringVertexEdge(7,"z");
  g2_e8 = new StringVertexEdge(8,"z");
  g2_e9 = new StringVertexEdge(9,"u");
  g2_e10 = new StringVertexEdge(10,"u");
  g2_e11 = new StringVertexEdge(11,"u");

  g2->add_vertex(g2_v1);
  g2->add_vertex(g2_v2);
  g2->add_vertex(g2_v3);
  g2->add_vertex(g2_v4);
  g2->add_vertex(g2_v5);
  g2->add_vertex(g2_v6);
  g2->add_vertex(g2_v7);
  g2->add_vertex(g2_v8);
  g2->add_vertex(g2_v9);

  g2->add_edge(g2_e1,g2_v1,g2_v2);
  g2->add_edge(g2_e2,g2_v2,g2_v3);
  g2->add_edge(g2_e3,g2_v3,g2_v4);
  g2->add_edge(g2_e4,g2_v4,g2_v5);
  g2->add_edge(g2_e5,g2_v5,g2_v6);
  g2->add_edge(g2_e6,g2_v6,g2_v7);
  g2->add_edge(g2_e7,g2_v7,g2_v8);
  g2->add_edge(g2_e8,g2_v8,g2_v9);
  g2->add_edge(g2_e9,g2_v9,g2_v1);
  g2->add_edge(g2_e10,g2_v1,g2_v7);
  g2->add_edge(g2_e11,g2_v1,g2_v8);
}

void ExpansionGraphTest::TearDown()
{
  delete g1_v1;
  delete g1_v2;
  delete g1_v3;
  delete g1_v4;
  delete g1_v5;
  delete g1_v6;
  delete g1_v7;
  delete g1_v8;
  delete g1_v9;

  delete g1_e1;
  delete g1_e2;
  delete g1_e3;
  delete g1_e4;
  delete g1_e5;
  delete g1_e6;
  delete g1_e7;
  delete g1_e8;
  delete g1_e9;
  delete g1_e10;
  delete g1_e11;

  delete g2_v1;
  delete g2_v2;
  delete g2_v3;
  delete g2_v4;
  delete g2_v5;
  delete g2_v6;
  delete g2_v7;
  delete g2_v8;
  delete g2_v9;

  delete g2_e1;
  delete g2_e2;
  delete g2_e3;
  delete g2_e4;
  delete g2_e5;
  delete g2_e6;
  delete g2_e7;
  delete g2_e8;
  delete g2_e9;
  delete g2_e10;
  delete g2_e11;

  delete g1;
  delete g2;
}

TEST_F(ExpansionGraphTest, Expansions)
{
  std::map<StringVertexEdge*, StringVertexEdge*> actual;
  g1->get_expansions(g1_v1, &actual);
  
  std::map<StringVertexEdge*, StringVertexEdge*> expected;
  expected.insert(std::pair<StringVertexEdge*,StringVertexEdge*>(g1_e1,g1_v2));
  expected.insert(std::pair<StringVertexEdge*,StringVertexEdge*>(g1_e10,g1_v7));
  expected.insert(std::pair<StringVertexEdge*,StringVertexEdge*>(g1_e11,g1_v8));
  expected.insert(std::pair<StringVertexEdge*,StringVertexEdge*>(g1_e9,g1_v9));

  EXPECT_TRUE(actual == expected);
}

TEST_F(ExpansionGraphTest, ExpansionsSubset)
{
  std::map<StringVertexEdge*, StringVertexEdge*> actual;
  
  std::set<StringVertexEdge*> constrain;
  constrain.insert(g1_e1);
  constrain.insert(g1_e10);

  g1->get_expansions_subset(g1_v1, &constrain, &actual);
  
  std::map<StringVertexEdge*, StringVertexEdge*> expected;
  expected.insert(std::pair<StringVertexEdge*, StringVertexEdge*>(g1_e10, g1_v7));
  expected.insert(std::pair<StringVertexEdge*, StringVertexEdge*>(g1_e1, g1_v2));
  
  EXPECT_TRUE(actual == expected);
}


